#ifndef LIB_H
#define LIB_H

#ifndef UNICODE
#error "PLIBC32 requires unicode"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if defined(_MSC_VER)
#pragma optimize("g", off)
#endif

#if defined PLIBDLL
#	if defined MAKEPLIBDLL
#		define PLIBEXP __declspec(dllexport)
#	else
#		define PLIBEXP __declspec(dllimport)
#	endif
#else
#	define PLIBEXP
#endif
#include <time.h>
typedef signed char			int8;
typedef signed short		int16;
typedef signed long			int32;
typedef __int64				int64;

typedef unsigned char		uint8;
typedef unsigned short		uint16;
typedef unsigned long		uint32;
typedef unsigned __int64	uint64;

typedef unsigned char		bool8;

typedef float Real;

#ifndef __DEBUG_H
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif
#define true				((bool8)1)
#define false				((bool8)0)
#endif

#ifdef DEBUG
#	if (_MSC_VER >= 800)
#		define breakpt()	__asm { int 3 }
#	else
#		define breakpt()
#	endif
#	include <stdio.h>
#   ifdef DEBUG_THREADMSG
#		include <windows.h>
#		define DEBUGMSG(x) { printf("%d: ", GetCurrentThreadId()); printf##x; wprintf("\n");}
#	else
#		define DEBUGMSG(x)	{char tmpbuf[128];_strdate_s( tmpbuf, 128 ); printf("[%s ",tmpbuf);_strtime_s( tmpbuf, 128 ); printf("%s] ",tmpbuf);printf##x; printf("\n"); }
#		define UDEBUGMSG(x)	{wchar_t tmpbuf[128];_wstrdate_s( tmpbuf, 128 ); wprintf(TEXT("[%s "),tmpbuf);_wstrtime_s( tmpbuf, 128 ); wprintf(TEXT("%s] "),tmpbuf);wprintf##x; wprintf(TEXT("\n")); }
#	endif
#	ifndef ASSERT
#		define ASSERT(x)	if (!(x)) { DEBUGMSG(("ASSERT FAILED: %s  (%s,%d)", \
							#x, __FILE__, __LINE__)); breakpt(); }
#	endif
#else
#   ifdef LOGRELEASE
#		include <stdio.h>
#		ifdef DEBUG_THREADMSG
#			include <windows.h>
#			define DEBUGMSG(x)	{ printf("%d: ", GetCurrentThreadId()); printf##x; printf("\n"); }
#			define UDEBUGMSG(x)	{ printf("%d: ", GetCurrentThreadId()); wprintf##x; wprintf(TEXT("\n")); }		
#		else
#			define DEBUGMSG(x)	{printf##x; printf("\n"); }
#			define UDEBUGMSG(x)	{wprintf##x; wprintf(TEXT("\n")); }
#		endif
#	else
#		define DEBUGMSG(x)
#		define UDEBUGMSG(x)
#	endif
#	ifndef ASSERT
#		define ASSERT(x)
#	endif
#endif

// Verify macro.  In debug builds this is the same as an ASSERT, but in
// release builds it does not go away like the ASSERT macro does.  Instead
// it still executes the passed in code.  This is useful for times when you
// want to assert that a function call succeeds in debug builds, but in 
// release builds you just want to call the function.
#ifndef VERIFY
#	ifdef DEBUG
#		define VERIFY(x) ASSERT(x)
#	else
#		define VERIFY(x) (x)
#	endif
#endif

// Compile time assert macro.  Useful for checking constant expressions
// that can be evaluated at compile time.
#ifndef C_ASSERT
#	define C_ASSERT(e) typedef char __C_ASSERT__[ ( e ) ? 1 : -1 ]
#endif

// countof macro that gives you the number of elements in a constant array.
// Commonly used with the C_ASSERT macro above.
#define countof( x ) ( sizeof( x ) / sizeof( x[0] ) )

//  Alignment Macros:
//      Align 'x' to 1, 2, 4, or 8 byte boundry.
#define ALIGNINT8(x)			(x)
#define ALIGNINT16(x)			(((x) + 1) & ~0x1)
#define ALIGNINT32(x)			(((x) + 3) & ~0x3)
#define ALIGNINT64(x)			(((x) + 7) & ~0x7)

#define ABS(x)					((x) < 0 ? -(x) : (x))
#define SQR(x)					((x) * (x))
#define MAX(x,y)				((x) > (y) ? (x) : (y))
#define MIN(x,y)				((x) < (y) ? (x) : (y))

#ifndef M_PI
#define M_PI		((Real)3.14159265358979323846f)
#endif
#define M_PIdiv180	((Real)0.01745329252165517991f)
#define DEG2RAD(x)	((Real)((x) * M_PIdiv180))

//
// UNICODE macros
//
#ifdef  UNICODE
#define __TEXT(quote) L##quote
#else   /* UNICODE */
#define __TEXT(quote) quote
#endif
#ifndef TEXT
#	define TEXT(quote) __TEXT(quote)
#endif

#define COLORSIZE			uint32      // kharmon.  05-08-06.  Improved Graphics.

PLIBEXP void setTransparentColor (uint8 r, uint8 g, uint8 b);
PLIBEXP COLORSIZE getTransparentColor ();

// kharmon.  05-08-06.  Improved Graphics.
PLIBEXP uint8 getBitsPerPixel();
PLIBEXP void setBitsPerPixel(uint8 ucBitsPerPixel);


PLIBEXP void setImageFormat (bool8 isRGB555);
PLIBEXP bool8 getImageFormat ();

// Defines for 16 bit images.  MS uses 2 16 bit modes, GRB555 and RGB565
// Convert 8bit GRB to the 16bit color space
#define RGB565(r, g, b)		((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3))
#define RGB555(r, g, b)		((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3))

// Extract component from 16 bit color space to an 8 bit component
#define R565(v)				(((v>>11)&0x1f)<<3)
#define G565(v)				(((v>>5)&0x3f)<<2)
#define B565(v)				(((v)&0x1f)<<3)

#define R555(v)				(((v>>10)&0x1f)<<3)
#define G555(v)				(((v>>5)&0x1f)<<3)
#define B555(v)				(((v)&0x1f)<<3)

// kharmon.  05-11-06.  Improved Graphics.  Updated to handle 16 and 24 bit modes.
#undef  GetGValue
#define GetGValue(rgb)      (LOBYTE(rgb >> 8))  // kharmon.  05-23-06.  Get rid of cast that triggered runtime warning.
#define GETRGB(R,G,B)		(getBitsPerPixel()==16?(getImageFormat()?RGB555(R, G, B):RGB565(R, G, B)):RGB(R, G, B))
#define GETR(c)				((uint8) (getBitsPerPixel()==16?(getImageFormat()?R555(c):R565(c)):GetRValue(c)))
#define GETG(c)				((uint8) (getBitsPerPixel()==16?(getImageFormat()?G555(c):G565(c)):GetGValue(c)))
#define GETB(c)				((uint8) (getBitsPerPixel()==16?(getImageFormat()?B555(c):B565(c)):GetBValue(c)))

#undef DIBINDEX
#define DIBINDEX(n)			RGB(GETR(n),GETG(n),GETB(n))

#define WHITE				GETRGB(255, 255, 255)
#define GREY				GETRGB(230, 230, 230)
#define CRYELLOW			GETRGB(243, 248, 82)
#define BLACK				GETRGB(0, 0, 0)
#define REELPTHIGHLIGHT		GETRGB(0, 255, 255)
#define TRANSCOLOR			getTransparentColor ()

#define TICKS_PER_SEC			1000
#define INVALIDTIME				((libtime)-1)
#define INSTANTANEOUS			0	/* Duration for immediate action */
typedef uint32 libtime;
PLIBEXP libtime TimerGetTime(void);

#ifdef __cplusplus
#  define __BEGIN_DECL		extern "C" {
#  define __END_DECL		}
#else
#  define __BEGIN_DECL
#  define __END_DECL
#endif

// Warning suppressors for unused variables.
#define NOTUSED(a)					((void)a);
#define NOTUSED2(a,b)				NOTUSED((a)); NOTUSED((b))
#define NOTUSED3(a,b,c)				NOTUSED((a)); NOTUSED2((b),(c))
#define NOTUSED4(a,b,c,d)			NOTUSED((a)); NOTUSED3((b),(c),(d))
#define NOTUSED5(a,b,c,d,e)			NOTUSED((a)); NOTUSED4((b),(c),(d),(e))
#define NOTUSED6(a,b,c,d,e,f)		NOTUSED((a)); NOTUSED5((b),(c),(d),(e),(f))

// A more useful version of #pragma message.
#define revisit_quote2(a)	#a
#define revisit_quote(a)	revisit_quote2(a)
#define revisit(msg)		message(__FILE__ "(" revisit_quote(__LINE__) "): revisit: " msg)
#define revisit_warn(msg)	message(__FILE__ "(" revisit_quote(__LINE__) "): warning: " msg)

// to avoid having the world depend on windows.h
#ifndef _WINDOWS_

#	ifndef NO_STRICT
#		ifndef STRICT
#			define STRICT 1
#		endif
#	endif /* NO_STRICT */

	typedef void *PVOID, *LPVOID;

#	ifdef STRICT
		typedef void *HANDLE;
#		define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#	else
		typedef PVOID HANDLE;
#	define DECLARE_HANDLE(name) typedef HANDLE name
#endif

	typedef unsigned int UINT;
	DECLARE_HANDLE(HINSTANCE);
	DECLARE_HANDLE(HWND);
	DECLARE_HANDLE(HDC);
	DECLARE_HANDLE(HBITMAP);
	DECLARE_HANDLE(HPALETTE);
	DECLARE_HANDLE(HPROPSHEETPAGE);
	typedef int BOOL;
	typedef long LONG;
	typedef char CHAR;
	typedef unsigned char BYTE;
	typedef unsigned short WORD;
#ifndef WCHAR
	typedef unsigned short WCHAR;
#endif
	typedef CHAR *LPSTR;
	typedef UINT WPARAM;
	typedef LONG LPARAM;
	typedef const CHAR *LPCSTR;
	typedef unsigned long DWORD;
	typedef WORD ATOM;
	typedef struct _RTL_CRITICAL_SECTION *PCRITICAL_SECTION;
	typedef struct _OVERLAPPED *LPOVERLAPPED;
	typedef struct tagPALETTEENTRY {
		BYTE        peRed;
		BYTE        peGreen;
		BYTE        peBlue;
		BYTE        peFlags;
	} PALETTEENTRY, *PPALETTEENTRY, *LPPALETTEENTRY;
	typedef struct tagRGBQUAD {
		BYTE    	rgbBlue;
		BYTE    	rgbGreen;
		BYTE    	rgbRed;
		BYTE    	rgbReserved;
	} RGBQUAD;
	typedef struct tagLOGPALETTE {
		WORD        palVersion;
		WORD        palNumEntries;
		PALETTEENTRY        palPalEntry[1];
	} LOGPALETTE;
	typedef struct tagTEXTMETRICW
	{
		LONG        tmHeight;
		LONG        tmAscent;
		LONG        tmDescent;
		LONG        tmInternalLeading;
		LONG        tmExternalLeading;
		LONG        tmAveCharWidth;
		LONG        tmMaxCharWidth;
		LONG        tmWeight;
		LONG        tmOverhang;
		LONG        tmDigitizedAspectX;
		LONG        tmDigitizedAspectY;
		WCHAR       tmFirstChar;
		WCHAR       tmLastChar;
		WCHAR       tmDefaultChar;
		WCHAR       tmBreakChar;
		BYTE        tmItalic;
		BYTE        tmUnderlined;
		BYTE        tmStruckOut;
		BYTE        tmPitchAndFamily;
		BYTE        tmCharSet;
	} TEXTMETRICW, *PTEXTMETRICW;
	typedef TEXTMETRICW TEXTMETRIC;

#ifndef RGB
#	define RGB(r,g,b)          ((int32)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#endif

#	if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#		define PASCAL	__stdcall
#	else
#		define PASCAL	pascal
#	endif
#	if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#		define CALLBACK    __stdcall
#	else
#		define CALLBACK
#	endif

#	define far
#	ifndef FAR
#		define FAR                 far
#	endif
	typedef struct tagRECT FAR *LPRECT;
#	define WM_USER		0x0400
#endif

#ifndef _WINSOCKAPI_		// to avoid having the world depend on winsock.h
	typedef unsigned int    u_int;
	typedef u_int           SOCKET;
	typedef struct sockaddr SOCKADDR;
	typedef struct sockaddr_in SOCKADDR_IN;
#endif

#ifndef _INC_COMMCTRL
	typedef struct tagNMCUSTOMDRAWINFO *LPNMCUSTOMDRAW;
#endif

#ifndef WM_APP
#define WM_APP                          0x8000
#endif

typedef struct _point
{
	int32	x;
	int32	y;
} point;
#define endianPoint		"w4w4"

typedef	struct _rect
{
	int32	left;
	int32	top;
	int32	right;
	int32	bottom;
} rect;
#define endianRect		"w4w4w4w4"

// access top left and bottom right of a rect
#define topleft(r)		(((pPoint) &(r))[0])
#define botright(r)		(((pPoint) &(r))[1])

typedef struct _RGBTriple
{
	uint8	red;
	uint8	green;
	uint8	blue;
} RGBTriple;
#define endianRGBTriple		"p1p1p1"

typedef struct _RGBQuad
{
	uint8	blue;
	uint8	green;
	uint8	red;
	uint8	reserved;
} RGBQuad;
#define endianRGBQuad		"p1p1p1p1"

typedef struct _CBitmap				* pCBitmap;
typedef struct _OldCBitmap			* pOldCBitmap;
typedef struct _CFrame				* pCFrame;
typedef struct _point				* ppoint;
typedef struct _rect				* prect;
typedef struct _CScreen				* pCScreen;
typedef struct _CScreenVTable		* pCScreenVTable;
typedef struct _CStaticHashTable	* pCStaticHashTable;
typedef struct _CStream				* pCStream;
typedef struct _CFixedBitmapFontDesc* pCFixedBitmapFontDesc;
typedef struct _CFixedBitmapFont	* pCFixedBitmapFont;
typedef struct _CSystemFont			* pCSystemFont;

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
// Class-Namespace declarations (please keep these in alphabetical order).
//
namespace Library
{
	class AmericanCodepage;
	class BlockedDataBuffer;
	class Bmp;
	class DigitsCodepage;
	class EuropeanCodepage;
	class FileStream;
	class Font;
	class KeywordSubstitutor;
	class LocaleFormatter;
	class MemoryStream;
	class Resource;
	class ResourceEntry;
	class ResourceEntryWriter;
	class ResourceFile;
	class ResourceFileWriter;
	class ResourceManager;
	class SouthAfricanCodepage;
	class Stream;
	class StrTableMgr;
	class TextBlock;
	class Thread;
	class VariableWidthFont;
};

// Class-Pointer declarations (please keep these in alphabetical order).
//
typedef class PLIBEXP Library::AmericanCodepage *		pAmericanCodepage;
typedef class PLIBEXP Library::BlockedDataBuffer *		pBlockedDataBuffer;
typedef class PLIBEXP Library::Bmp *					pBmp;
typedef class PLIBEXP Library::DigitsCodepage *			pDigitsCodepage;
typedef class PLIBEXP Library::EuropeanCodepage *		pEuropeanCodepage;
typedef class PLIBEXP Library::FileStream *				pFileStream;
typedef class PLIBEXP Library::Font *					pFont;
typedef class PLIBEXP Library::KeywordSubstitutor *		pKeywordSubstitutor;
typedef class PLIBEXP Library::LocaleFormatter *		pLocaleFormatter;
typedef class PLIBEXP Library::MemoryStream *			pMemoryStream;
typedef class PLIBEXP Library::Resource *				pResource;
typedef class PLIBEXP Library::ResourceEntry *			pResourceEntry;
typedef class PLIBEXP Library::ResourceEntryWriter *	pResourceEntryWriter;
typedef class PLIBEXP Library::ResourceFile *			pResourceFile;
typedef class PLIBEXP Library::ResourceFileWriter *		pResourceFileWriter;
typedef class PLIBEXP Library::ResourceManager *		pResourceManager;
typedef class PLIBEXP Library::SouthAfricanCodepage *	pSouthAfricanCodepage;
typedef class PLIBEXP Library::Stream *					pStream;
typedef class PLIBEXP Library::StrTableMgr *			pStrTableMgr;
typedef class PLIBEXP Library::TextBlock *				pTextBlock;
typedef class PLIBEXP Library::Thread *					pThread;
typedef class PLIBEXP Library::VariableWidthFont *		pVariableWidthFont;
typedef class PLIBEXP SystemFont *						pCFont;
typedef class PLIBEXP TabControl *						pTabControl;
typedef class PLIBEXP TabControlPage *					pTabControlPage;

// Turn off warning caused by STL long template names
#pragma warning(disable:4786)

// Turn off warning caused by push_macro to push/pop "new" in release builds
#pragma warning(disable:4601)

#pragma warning (disable:4800) // CSN-12948 - Upgrade to VS2012

// STL functions that use 'new' must be included before DebugMemoryLeaks
// (failing to do so causes compile-time errors in Visual Studio .NET 2003)
#if _MSC_VER >= 1300
#pragma warning( push )
#pragma warning(disable:4530)
#include <list>
#include <map>
#pragma warning( pop )
#endif

// Include ProtectedMemory before DebugMemoryLeaks
#include "win32\protectedmemory.h"

// Debug memory functions are used by everthing
#ifdef _DEBUG
#include "DebugMemoryLeaks.h"
#endif

#include "ustring.h"				//the string class is used by everything

using namespace Library;

#endif


#endif
